#include "domainquerytask.h"
//#include <QNetworkAccessManager>
//#include <QNetworkReply>
//#include <QNetworkRequest>
//#include <QEventLoop>
//#include <QUrl>
//#include <QNetworkProxy>
//#include <QCoreApplication>
#include "global.h"
//#include "precomp.h"

DomainQueryTask::DomainQueryTask(QAtomicInt &finishedTasks,const SocketDnInfo &sdni, QObject *parent)
    : m_finishedTasks(finishedTasks), m_sdni(sdni),QObject(parent)
{
    //m_recvBuffer.clear();
    //m_finishedTasks= finishedTasks;

}

DomainQueryTask::~DomainQueryTask()
{
   // qDebug()<<__FUNCTION__<<m_sdni.reqParam;
}

void DomainQueryTask::run()
{
    //开始测试代码
    // QByteArray strss="Domain Name: 90.app\r\nRegistry Domain ID: 2CA8E1B6E-APP\r\nRegistrar WHOIS Server: whois.enom.com\r\nRegistrar URL: http://www.enom.com\r\nUpdated Date: 2022-01-23T21:44:56Z\r\nCreation Date: 2018-05-05T12:58:43Z\r\nRegistry Expiry Date: 2025-05-05T12:58:43Z\r\nRegistrar: eNom, Inc.\r\nRegistrar IANA ID: 48\r\nRegistrar Abuse Contact Email: abuse@enom.com\r\nRegistrar Abuse Contact Phone: +1.8556000886\r\nDomain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited\r\nRegistry Registrant ID: REDACTED FOR PRIVACY\r\nRegistrant Name: REDACTED FOR PRIVACY\r\nRegistrant Organization: NA\r\nRegistrant Street: REDACTED FOR PRIVACY\r\nRegistrant City: REDACTED FOR PRIVACY\r\nRegistrant State/Province:\r\nRegistrant Postal Code:\r\nRegistrant Country: US\r\nRegistrant Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nRegistry Admin ID: REDACTED FOR PRIVACY\r\nAdmin Name: REDACTED FOR PRIVACY\r\nAdmin Organization: REDACTED FOR PRIVACY\r\nAdmin Street: REDACTED FOR PRIVACY\r\nAdmin City: REDACTED FOR PRIVACY\r\nAdmin State/Province:\r\nAdmin Postal Code:\r\nAdmin Country: REDACTED FOR PRIVACY\r\nAdmin Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nRegistry Tech ID: REDACTED FOR PRIVACY\r\nTech Name: REDACTED FOR PRIVACY\r\nTech Organization: REDACTED FOR PRIVACY\r\nTech Street: REDACTED FOR PRIVACY\r\nTech City: REDACTED FOR PRIVACY\r\nTech State/Province:\r\nTech Postal Code:\r\nTech Country: REDACTED FOR PRIVACY\r\nTech Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nRegistry Billing ID: REDACTED FOR PRIVACY\r\nBilling Name: REDACTED FOR PRIVACY\r\nBilling Organization: REDACTED FOR PRIVACY\r\nBilling Street: REDACTED FOR PRIVACY\r\nBilling City: REDACTED FOR PRIVACY\r\nBilling State/Province:\r\nBilling Postal Code:\r\nBilling Country: REDACTED FOR PRIVACY\r\nBilling Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nName Server: ns1lmy.name.com\r\nName Server: ns2ckr.name.com\r\nName Server: ns3fhx.name.com\r\nName Server: ns4lny.name.com\r\nDNSSEC: unsigned\r\nURL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/\r\n>>> Last update of WHOIS database: 2024-05-17T14:40:59Z <<<\r\n\r\nFor more information on Whois status codes, please visit https://icann.org/epp\r\n\r\nPlease query the WHOIS server of the owning registrar identified in this\r\noutput for information on how to contact the Registrant, Admin, or Tech\r\ncontact of the queried domain name.\r\n\r\nWHOIS information is provided by Charleston Road Registry Inc. (CRR) solely\r\nfor query-based, informational purposes. By querying our WHOIS database, you\r\nare agreeing to comply with these terms\r\n(https://www.registry.google/about/whois-disclaimer.html) and acknowledge\r\nthat your information will be used in accordance with CRR's Privacy Policy\r\n(https://www.registry.google/about/privacy.html), so please read those\r\ndocuments carefully.  Any information provided is \"as is\" without any\r\nguarantee of accuracy. You may not use such information to (a) allow,\r\nenable, or otherwise support the transmission of mass unsolicited,\r\ncommercial advertising or solicitations; (b) enable high volume, automated,\r\nelectronic processes that access the systems of CRR or any ICANN-Accredited\r\nRegistrar, except as reasonably necessary to register domain names or modify\r\nexisting registrations; or (c) engage in or support unlawful behavior. CRR\r\nreserves the right to restrict or deny your access to the Whois database,\r\nand may modify these terms at any time.\r\n";
    // DomainInfo di=g_ParseBytesToDomainInfo(strss,m_sdni.reqParam,m_sdni.Id);
    // GlobalQueue* queue = GlobalQueueSingleton::instance();
    // queue->enqueue(di);
    // m_finishedTasks.fetchAndAddOrdered(1); // 完成任务计数+1
    // return;
    //结束测试代码
    QTcpSocket *socket = new QTcpSocket();
    socket->setReadBufferSize(1024 * 1024);
    QByteArray recvBuffer; // 定义response变量来累积接收的数据
    // 连接到服务器
    m_host=m_sdni.address;
    m_port=m_sdni.port.toInt();

    if (g_enableProxy) {
        QString proxyStr = g_proxyPool.getNextProxy();
        if (proxyStr.length() == 0) {
            qDebug() << "获取代理失败" << m_sdni.reqParam;
            return;
        }
        m_proxyHost = proxyStr.left(proxyStr.indexOf(':'));
        m_proxyPort = proxyStr.section(':', 1, 1).toInt();

        QNetworkProxy proxy;
        proxy.setType(QNetworkProxy::Socks5Proxy);
        proxy.setHostName(m_proxyHost);
        proxy.setPort(m_proxyPort);
        socket->setProxy(proxy);
    }

    qDebug()<<"开始连接"<<m_sdni.reqParam<<"proxy:"<<m_proxyHost<<"host:"<<m_host<<"port:"<<m_port<<QThread::currentThreadId();
    socket->connectToHost(m_host, m_port);

    // 等待连接
    if (socket->waitForConnected(10000)) {
        // 连接成功，发送数据
        socket->write(m_sdni.msg.toUtf8()+ "\n");
        socket->flush();

        socket->waitForBytesWritten(10000); // 等待数据发送完成
        //qDebug()<<"发送数据:param"<<m_sdni.reqParam<<"host"<<m_sdni.address<<"port"<<m_sdni.port<<"msg"<<m_sdni.msg;
        bool shouldExit = false;
        while (true) {
            // 检查是否有未读数据
            if (socket->bytesAvailable()) {

                QByteArray data = socket->readAll(); // 读取当前缓冲区所有数据
                qDebug()<<" 处理读取到的数据"<<data.length()<<shouldExit<<m_sdni.reqParam;
                recvBuffer.append(data);
                if (shouldExit) {
                    //qDebug()<<"exit";
                    break;
                }
            } else {
                qDebug()<<"没有未读数据，等待新的数据到达"<<m_sdni.reqParam;
                if (!socket->waitForReadyRead(5000)) { // 等待5秒，如果超时则继续检查
                    //qDebug()<<"5秒未读到数据,退出"<<m_sdni.reqParam;
                    shouldExit = true;
                    break;
                }
            }
        }
        //qDebug() <<recvBuffer;
        //qDebug() << "Response:" << m_sdni.reqParam<<recvBuffer.length()<<QThread::currentThreadId();
        //QByteArray strss="Domain Name: 90.app\r\nRegistry Domain ID: 2CA8E1B6E-APP\r\nRegistrar WHOIS Server: whois.enom.com\r\nRegistrar URL: http://www.enom.com\r\nUpdated Date: 2022-01-23T21:44:56Z\r\nCreation Date: 2018-05-05T12:58:43Z\r\nRegistry Expiry Date: 2025-05-05T12:58:43Z\r\nRegistrar: eNom, Inc.\r\nRegistrar IANA ID: 48\r\nRegistrar Abuse Contact Email: abuse@enom.com\r\nRegistrar Abuse Contact Phone: +1.8556000886\r\nDomain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited\r\nRegistry Registrant ID: REDACTED FOR PRIVACY\r\nRegistrant Name: REDACTED FOR PRIVACY\r\nRegistrant Organization: NA\r\nRegistrant Street: REDACTED FOR PRIVACY\r\nRegistrant City: REDACTED FOR PRIVACY\r\nRegistrant State/Province:\r\nRegistrant Postal Code:\r\nRegistrant Country: US\r\nRegistrant Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nRegistry Admin ID: REDACTED FOR PRIVACY\r\nAdmin Name: REDACTED FOR PRIVACY\r\nAdmin Organization: REDACTED FOR PRIVACY\r\nAdmin Street: REDACTED FOR PRIVACY\r\nAdmin City: REDACTED FOR PRIVACY\r\nAdmin State/Province:\r\nAdmin Postal Code:\r\nAdmin Country: REDACTED FOR PRIVACY\r\nAdmin Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nRegistry Tech ID: REDACTED FOR PRIVACY\r\nTech Name: REDACTED FOR PRIVACY\r\nTech Organization: REDACTED FOR PRIVACY\r\nTech Street: REDACTED FOR PRIVACY\r\nTech City: REDACTED FOR PRIVACY\r\nTech State/Province:\r\nTech Postal Code:\r\nTech Country: REDACTED FOR PRIVACY\r\nTech Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nRegistry Billing ID: REDACTED FOR PRIVACY\r\nBilling Name: REDACTED FOR PRIVACY\r\nBilling Organization: REDACTED FOR PRIVACY\r\nBilling Street: REDACTED FOR PRIVACY\r\nBilling City: REDACTED FOR PRIVACY\r\nBilling State/Province:\r\nBilling Postal Code:\r\nBilling Country: REDACTED FOR PRIVACY\r\nBilling Email: Please query the WHOIS server of the owning registrar identified in this output for information on how to contact the Registrant, Admin, or Tech contact of the queried domain name. \r\nName Server: ns1lmy.name.com\r\nName Server: ns2ckr.name.com\r\nName Server: ns3fhx.name.com\r\nName Server: ns4lny.name.com\r\nDNSSEC: unsigned\r\nURL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/\r\n>>> Last update of WHOIS database: 2024-05-17T14:40:59Z <<<\r\n\r\nFor more information on Whois status codes, please visit https://icann.org/epp\r\n\r\nPlease query the WHOIS server of the owning registrar identified in this\r\noutput for information on how to contact the Registrant, Admin, or Tech\r\ncontact of the queried domain name.\r\n\r\nWHOIS information is provided by Charleston Road Registry Inc. (CRR) solely\r\nfor query-based, informational purposes. By querying our WHOIS database, you\r\nare agreeing to comply with these terms\r\n(https://www.registry.google/about/whois-disclaimer.html) and acknowledge\r\nthat your information will be used in accordance with CRR's Privacy Policy\r\n(https://www.registry.google/about/privacy.html), so please read those\r\ndocuments carefully.  Any information provided is \"as is\" without any\r\nguarantee of accuracy. You may not use such information to (a) allow,\r\nenable, or otherwise support the transmission of mass unsolicited,\r\ncommercial advertising or solicitations; (b) enable high volume, automated,\r\nelectronic processes that access the systems of CRR or any ICANN-Accredited\r\nRegistrar, except as reasonably necessary to register domain names or modify\r\nexisting registrations; or (c) engage in or support unlawful behavior. CRR\r\nreserves the right to restrict or deny your access to the Whois database,\r\nand may modify these terms at any time.\r\n";
        DomainInfo di=g_ParseBytesToDomainInfo(recvBuffer,m_sdni.reqParam,m_sdni.Id);
        GlobalQueue* queue = GlobalQueueSingleton::instance();
        queue->enqueue(di);
        m_finishedTasks.fetchAndAddOrdered(1); // 完成任务计数+1
        //emit validationResult(recvBuffer, m_sdni.reqParam);
        // 关闭连接
        socket->close();
    } else {
        qDebug() << "连接失败！"<<m_sdni.reqParam<<"proxy:"<<m_proxyHost<<"host:"<<m_host<<"port:"<<m_port;
    }
    // 删除对象
    delete socket;

}
/*
void DomainQueryTask::run()
{
    QString proxyStr = g_proxyPool.getNextProxy();
    if(proxyStr.length()==0)
    {
        qDebug()<<"获取代理失败"<<m_sdni.reqParam;
        return;
    }
    m_proxyHost=proxyStr.left(proxyStr.indexOf(':'));
    m_proxyPort=proxyStr.section(':', 1, 1).toInt();

    QNetworkProxy proxy;
    proxy.setType(QNetworkProxy::Socks5Proxy);
    proxy.setHostName(m_proxyHost);
    proxy.setPort(m_proxyPort);
    QByteArray recvBuffer;
    recvBuffer.clear();
    //m_tcpSocket = new QTcpSocket();

//    connect(m_tcpSocket, &QTcpSocket::connected, this, &DomainQueryTask::sendMessage,Qt::DirectConnection);
//    connect(m_tcpSocket, &QTcpSocket::readyRead, this, &DomainQueryTask::handleDataReceived,Qt::DirectConnection);
//    connect(m_tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::errorOccurred), this, &DomainQueryTask::socketError,Qt::DirectConnection);

    QTcpSocket tcpSocket;

    //m_tcpSocket->setProxy(proxy);

    m_host=m_sdni.address;
    m_port=m_sdni.port.toInt();
    qDebug()<<"开始连接代理"<<m_sdni.reqParam<<"proxy:"<<m_proxyHost<<"host:"<<m_host<<"port:"<<m_port;

    connect(&tcpSocket, &QTcpSocket::connected, this, [&](){
            if (tcpSocket.state() != QAbstractSocket::ConnectedState)
                return;
            tcpSocket.write(m_sdni.msg.toUtf8()+ "\n");
            tcpSocket.flush();

            qDebug()<<"发送数据:param"<<m_sdni.reqParam<<"host"<<m_sdni.address<<"port"<<m_sdni.port<<"msg"<<m_sdni.msg;
            tcpSocket.waitForReadyRead(10000); // 等待服务器响应，超时时间为10秒
        },Qt::DirectConnection);
    connect(&tcpSocket, &QTcpSocket::readyRead, this, [&](){
            while (tcpSocket.bytesAvailable())
            {
                recvBuffer += tcpSocket.readAll();
            }
        },Qt::DirectConnection);

    connect(&tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::errorOccurred), this, [&](QAbstractSocket::SocketError error){
//            switch (error) {
//            case QAbstractSocket::RemoteHostClosedError:
//                qDebug() << "Server has closed connection"<<m_sdni.reqParam<<recvBuffer.length();//<<m_recvBuffer;
//            default:
//                qWarning() << "An error occurred: " << tcpSocket.errorString();
//                //emit validationResult(recvBuffer, m_sdni.reqParam);  // 替换为实际的请求ID
//                //QMetaObject::invokeMethod(this, "stopTask", Qt::QueuedConnection);
//            }
            qDebug() << "error: " << m_sdni.reqParam<<tcpSocket.tcpSocket.errorString();
            emit validationResult(recvBuffer, m_sdni.reqParam);
            tcpSocket.abort();


        },Qt::DirectConnection);

    QEventLoop loop;
    tcpSocket.connectToHost(m_host, m_port);
    if (tcpSocket.waitForConnected(10000)) { // 等待连接建立，超时时间为10秒
        // 连接成功
        qDebug()<<"连接成功"<<m_host;
    } else {
        // 连接失败
        qDebug()<<"连接失败"<<m_host;
    }
    connect(this, &DomainQueryTask::validationResult, &loop, &QEventLoop::quit);

    loop.exec(); // 等待请求完成

}
*/


void DomainQueryTask::stopTask()
{
    //qDebug()<<"stopTask";
    emit exitTask();
}
void DomainQueryTask::sendMessage()
{
//    if (m_tcpSocket->state() != QAbstractSocket::ConnectedState)
//        return;

//    m_tcpSocket->write(m_sdni.msg.toUtf8()+ "\n");
//    m_tcpSocket->flush();
//    qDebug()<<"send msg:param"<<m_sdni.reqParam<<"host"<<m_sdni.address<<"port"<<m_sdni.port<<"msg"<<m_sdni.msg;
}
void DomainQueryTask::handleDataReceived()
{
//    while (m_tcpSocket->bytesAvailable())
//    {
//        m_recvBuffer += m_tcpSocket->readAll();
//    }

}
void DomainQueryTask::socketError(QAbstractSocket::SocketError error)
{
/*
    switch (error) {
    case QAbstractSocket::RemoteHostClosedError:
        qDebug() << "Server has closed connection"<<m_sdni.reqParam<<m_recvBuffer.length();//<<m_recvBuffer;
        if(m_recvBuffer.length())//有数据才发送信息进行处理
        {
            emit validationResult(m_recvBuffer, m_sdni.reqParam);  // 替换为实际的请求ID
            //qDebug() <<"emit dataSocketReceived "<<m_reqParam;
        }
        break;
    default:
        qWarning() << "An error occurred: " << m_tcpSocket->errorString();
        emit validationResult(m_recvBuffer, m_sdni.reqParam);
        break;
    }
*/
    //deleteLater();
}
